﻿using System;
using System.Configuration;
using System.IO;
using NUnit.Framework;
using SeleniumToolkit.Config;
using System.Threading;

namespace SeleniumToolkit.Core
{
    public class SeleniumRemoteControlHostSpecs : SpecFor<SeleniumRemoteControlHost>
    {
        protected SeleniumConfiguration config;
        protected string InstallPath = ConfigurationManager.AppSettings["SeleniumRCPath"];

        protected override void Context()
        {
            config = new SeleniumConfiguration();
            config.RuntimeSettings.SeleniumRuntimePath = InstallPath;
        }

        public override SeleniumRemoteControlHost InitializeSubject()
        {
            return new SeleniumRemoteControlHost(config);
        }

        [TestFixture]
        public class WhenStartingWithJavaNotInstalled : SeleniumRemoteControlHostSpecs
        {
            string classPath;
            string path;

            protected override void Context_BeforeAllSpecs()
            {
                // get current class path
                classPath = Environment.GetEnvironmentVariable("CLASSPATH");
                path = Environment.GetEnvironmentVariable("PATH");


                // remove current class path
                Environment.SetEnvironmentVariable("CLASSPATH", null);
                Environment.SetEnvironmentVariable("PATH", null);
            }

            protected override void CleanUpContext_AfterAllSpecs()
            {
                // restore original class path
                Environment.SetEnvironmentVariable("CLASSPATH", classPath);
                Environment.SetEnvironmentVariable("PATH", path);
                Assert.IsNotNull(path, "Path was set to null.");
            }

            protected override void Because()
            {
                exception = ((MethodThatThrows) delegate() 
                                { 
                                    subject.Start(); 
                                }
                             ).GetException();
            }

            [Test]
            public void ShouldThrowErrorWhenTryingToStart()
            {
                exception.ShouldNotBeNull();
            }

            [Test]
            public void ShouldContainErrorMessageAboutMissingJavaRuntime()
            {
                exception.ShouldContainErrorMessage("Unable to start selenium host process");
            }
        }

        [TestFixture]
        public class WhenStartingWithJavaInstalled : SeleniumRemoteControlHostSpecs
        {
            protected override void Because()
            {
                subject.Running.ShouldBeFalse("Host should not be running.");
                subject.Start();
            }

            protected override void CleanUpContext()
            {
                subject.Stop();
                subject.Running.ShouldBeFalse("Host should have shutdown");
            }

            [Test]
            public void ShouldStartNormally()
            {
                subject.Running.ShouldBeTrue("Host is not running.");
            }
        }


        [TestFixture]
        public class WhenFolderPathIsIncorrect : SeleniumRemoteControlHostSpecs
        {
            protected override void Context()
            {
                base.Context();
                config.RuntimeSettings.SeleniumRuntimePath = @"C:\";
            }

            protected override void Because()
            {
                exception = ((MethodThatThrows)delegate()
                                {
                                    subject.Start();
                                }
                            ).GetException();
            }

            [Test]
            public void ShouldThrowErrorWhenTryingToStart()
            {
                exception.ShouldNotBeNull();
                exception.ShouldBeOfType(typeof(FileNotFoundException));
            }

            [Test]
            public void ShouldIncludeHelpfulErrorMessage()
            {
                exception.ShouldContainErrorMessage("Unable to locate the selenium");
            }
        }
    }
}
